package rexsee.security;

import java.security.MessageDigest;
import java.security.Security;

import rexsee.core.application.RexseeApplication;
import rexsee.core.browser.Browser;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.browser.clazz.SyncTask;
import rexsee.core.browser.clazz.SyncTask.StringRunnable;
import rexsee.core.utilities.Json;
import rexsee.core.utilities.Utilities;

public class RexseeDigest implements JavascriptInterface {

	public static final String INTERFACE_NAME = "Digest";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return this;
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseeDigest(childBrowser);
	}

	private final Browser mBrowser;

	public RexseeDigest(Browser browser) {
		mBrowser = browser;
	}

	private String get_(final String algorithm, String string, boolean isFile, boolean showProgress, boolean cancelable) {
		final byte[] bytes = (isFile) ? Utilities.getContent(string) : string.getBytes();
		if (bytes == null) return RexseeApplication.EXCEPTION_PREFIX + "Error on reading source data.";
		StringRunnable runnable = new StringRunnable() {
			@Override
			public String run() {
				try {
					byte[] digest = null;
					MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
					messageDigest.update(bytes);
					digest = messageDigest.digest();
					return RexseeSecurity.bytes2hex(digest);
				} catch (Exception e) {
					return RexseeApplication.EXCEPTION_PREFIX + e.getLocalizedMessage();
				}
			}
		};
		if (showProgress) {
			return new SyncTask().run(runnable, mBrowser, cancelable);
		} else {
			return new SyncTask().run(runnable, null, false);
		}
	}

	//JavaScript interface
	public String getAlgorithms() {
		return Json.toJson(Security.getAlgorithms("MessageDigest"));
	}
	public String get(String algorithm, String string) {
		return get_(algorithm, string, false, false, false);
	}
	public String get(String algorithm, String string, boolean isFile, boolean showProgress, boolean cancelable) {
		return get_(algorithm, string, isFile, showProgress, cancelable);
	}

}
